<

ファイルの読み取りと書き込み

場合によっては、ファイルをディスクに読み書きする必要があります。 たとえば、アプリの起動後もデータを保持する必要がある場合があります。 または、インターネットからデータをダウンロードして、後でオフラインで使用できるように保存します。

モバイルまたはデスクトップ アプリでファイルをディスクに保存するには、 を組み合わせるpath_providerプラグインdart:io図書館。

このレシピでは次の手順を使用します。

  1. 正しいローカル パスを見つけます。
  2. ファイルの場所への参照を作成します。
  3. データをファイルに書き込みます。
  4. ファイルからデータを読み取ります。

詳細については、今週のパッケージのビデオをご覧ください。 でpath_providerパッケージ:

1. 正しいローカル パスを見つける

この例ではカウンターを表示します。カウンターが変わると、 データをディスクに書き込むと、アプリのロード時に再度読み取ることができます。 このデータはどこに保存すればよいでしょうか?

path_providerパッケージ は、プラットフォームに依存せずに、一般的に使用される場所にアクセスする方法を提供します。 デバイスのファイル システム。このプラグインは現在、次へのアクセスをサポートしています。 ファイル システムの 2 つの場所:

一時ディレクトリ
システムが使用できる一時ディレクトリ (キャッシュ) いつでもクリア。 iOS では、これはNSCachesDirectory。 Android では、これは次の値です。getCacheDir()戻り値。
ドキュメントディレクトリ
アプリがファイルを保存するためのディレクトリ。 アクセスできるのです。システムは、アプリが次の場合にのみディレクトリをクリアします。 が削除されます。 iOS では、これはNSDocumentDirectory。 Android では、これはAppDataディレクトリ。

この例では、情報をドキュメント ディレクトリに保存します。 次のようにして、ドキュメント ディレクトリへのパスを見つけることができます。

Future<String> get _localPath async {
  final directory = await getApplicationDocumentsDirectory();

  return directory.path;
}

2. ファイルの場所への参照を作成します。

ファイルの保存場所がわかったら、への参照を作成します。 ファイルの完全な場所。使用できますFileからのクラスdart:ioこれを実現するライブラリ。

Future<File> get _localFile async {
  final path = await _localPath;
  return File('$path/counter.txt');
}

3. ファイルにデータを書き込む

これで、File一緒に働くために、 データの読み取りと書き込みに使用します。 まず、ファイルにデータを書き込みます。 カウンタは整数ですが、 ファイルを文字列として使用して、902ecd38-c1d3-49e5-ベッド1-902d0f59bf3e構文。

Future<File> writeCounter(int counter) async {
  final file = await _localFile;

  // Write the file
  return file.writeAsString('$counter');
}

4. ファイルからデータを読み取る

ディスク上にデータが保存されたので、それを読み取ることができます。 もう一度、Fileクラス。

Future<int> readCounter() async {
  try {
    final file = await _localFile;

    // Read the file
    final contents = await file.readAsString();

    return int.parse(contents);
  } catch (e) {
    // If encountering an error, return 0
    return 0;
  }
}

完全な例

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(
    MaterialApp(
      title: 'Reading and Writing Files',
      home: FlutterDemo(storage: CounterStorage()),
    ),
  );
}

class CounterStorage {
  Future<String> get _localPath async {
    final directory = await getApplicationDocumentsDirectory();

    return directory.path;
  }

  Future<File> get _localFile async {
    final path = await _localPath;
    return File('$path/counter.txt');
  }

  Future<int> readCounter() async {
    try {
      final file = await _localFile;

      // Read the file
      final contents = await file.readAsString();

      return int.parse(contents);
    } catch (e) {
      // If encountering an error, return 0
      return 0;
    }
  }

  Future<File> writeCounter(int counter) async {
    final file = await _localFile;

    // Write the file
    return file.writeAsString('$counter');
  }
}

class FlutterDemo extends StatefulWidget {
  const FlutterDemo({super.key, required this.storage});

  final CounterStorage storage;

  @override
  State<FlutterDemo> createState() => _FlutterDemoState();
}

class _FlutterDemoState extends State<FlutterDemo> {
  int _counter = 0;

  @override
  void initState() {
    super.initState();
    widget.storage.readCounter().then((value) {
      setState(() {
        _counter = value;
      });
    });
  }

  Future<File> _incrementCounter() {
    setState(() {
      _counter++;
    });

    // Write the variable as a string to the file.
    return widget.storage.writeCounter(_counter);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Reading and Writing Files'),
      ),
      body: Center(
        child: Text(
          'Button tapped $_counter time${_counter == 1 ? '' : 's'}.',
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}